package com.sip.dbadapter.dao.impl;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.sip.dbadapter.dao.domain.ApiDefinition;
import com.sip.dbadapter.dao.domain.SystemInfo;
import com.sip.dbadapter.dao.interfaces.FilteringDAO;

public class FilteringDAOImpl extends BusinessDaoImpl<Object, Serializable> implements FilteringDAO<Object>{

    private String EMPTY_STRING = "";
    
	@Override
	protected Class<Object> getDomainClass() {
		// TODO Auto-generated method stub
		return null;
	}

	public List<ApiDefinition> searchTest(final ApiDefinition apiDefinition, final SystemInfo systemInfo) throws Exception {
	       
	    String systemName = systemInfo.getSystemName();
	    String packageName = apiDefinition.getPackageHierachy();
	    String apiName = apiDefinition.getName();
	    
        if (!systemName.equals(EMPTY_STRING) && packageName.equals(EMPTY_STRING) && apiName.equals(EMPTY_STRING)) {  // SYSTEM_NAME
            
            final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo " +
                "where sysinfo.systemName=:"+QueryParams.KEY_SYSTEM_NAME.getValue()+" and apidef.apiStatus=:"+QueryParams.KEY_API_STATUS.getValue();
        
            Map<String, Object> queryParams = new HashMap<String, Object>();System.out.println("------------===// SYSTEM_NAME");
            queryParams.put(QueryParams.KEY_SYSTEM_NAME.getValue(), systemName);
            queryParams.put(QueryParams.KEY_API_STATUS.getValue(), "ACTIVE");
        
            return getResults(query, queryParams);
            
        } else if (!systemName.equals(EMPTY_STRING) && !packageName.equals(EMPTY_STRING) && apiName.equals(EMPTY_STRING)) {  // SYSTEM_NAME && PACKAGE_NAME
            
            final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo " +
                "where sysinfo.systemName=:"+QueryParams.KEY_SYSTEM_NAME.getValue()+
                " and apidef.apiStatus=:"+QueryParams.KEY_API_STATUS.getValue()+
                " and apidef.packageHierachy=:"+QueryParams.KEY_PACKAGE_NAME.getValue();
        
            Map<String, Object> queryParams = new HashMap<String, Object>();System.out.println("------------===// SYSTEM_NAME && PACKAGE_NAME");
            queryParams.put(QueryParams.KEY_SYSTEM_NAME.getValue(), systemName);
            queryParams.put(QueryParams.KEY_PACKAGE_NAME.getValue(), packageName);
            queryParams.put(QueryParams.KEY_API_STATUS.getValue(), "ACTIVE");
        
            return getResults(query, queryParams);
            
        } else if (!systemName.equals(EMPTY_STRING) && !packageName.equals(EMPTY_STRING) && !apiName.equals(EMPTY_STRING)) {  // SYSTEM_NAME && PACKAGE_NAME && API_NAME
            
            final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo " +
                "where apidef.name like :"+QueryParams.KEY_API_NAME.getValue()+" and sysinfo.systemName=:"+QueryParams.KEY_SYSTEM_NAME.getValue()+
                " and apidef.packageHierachy=:"+QueryParams.KEY_PACKAGE_NAME.getValue()+" and apidef.apiStatus=:"+QueryParams.KEY_API_STATUS.getValue();
        
            Map<String, Object> queryParams = new HashMap<String, Object>();System.out.println("------------===// SYSTEM_NAME && PACKAGE_NAME && API_NAME");
            queryParams.put(QueryParams.KEY_SYSTEM_NAME.getValue(), systemName);
            queryParams.put(QueryParams.KEY_PACKAGE_NAME.getValue(), packageName);
            queryParams.put(QueryParams.KEY_API_NAME.getValue(), apiName);
            queryParams.put(QueryParams.KEY_API_STATUS.getValue(), "ACTIVE");
        
            return getResults(query, queryParams);
            
        } else if (systemName.equals(EMPTY_STRING) && !packageName.equals(EMPTY_STRING) && apiName.equals(EMPTY_STRING)) {  // PACKAGE_NAME
            
            final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo " +
                "where apidef.packageHierachy=:"+QueryParams.KEY_PACKAGE_NAME.getValue()+" and apidef.apiStatus=:"+QueryParams.KEY_API_STATUS.getValue();
        
            Map<String, Object> queryParams = new HashMap<String, Object>();System.out.println("------------===// PACKAGE_NAME");
            queryParams.put(QueryParams.KEY_PACKAGE_NAME.getValue(), packageName);
            queryParams.put(QueryParams.KEY_API_STATUS.getValue(), "ACTIVE");
            
            return getResults(query, queryParams);
            
        } else if (systemName.equals(EMPTY_STRING) && !packageName.equals(EMPTY_STRING) && !apiName.equals(EMPTY_STRING)) {  // PACKAGE_NAME && API_NAME
            
            final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo " +
                "where apidef.name like :"+QueryParams.KEY_API_NAME.getValue()+" and apidef.packageHierachy=:"+QueryParams.KEY_PACKAGE_NAME.getValue()+" and apidef.apiStatus=:"+QueryParams.KEY_API_STATUS.getValue();
        
            Map<String, Object> queryParams = new HashMap<String, Object>();System.out.println("------------===// PACKAGE_NAME && API_NAME");
            queryParams.put(QueryParams.KEY_PACKAGE_NAME.getValue(), packageName);
            queryParams.put(QueryParams.KEY_API_NAME.getValue(), apiName);
            queryParams.put(QueryParams.KEY_API_STATUS.getValue(), "ACTIVE");
        
            return getResults(query, queryParams);
            
        } else if (systemName.equals(EMPTY_STRING) && packageName.equals(EMPTY_STRING) && !apiName.equals(EMPTY_STRING)) {  // API_NAME
            
            final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo " +
                "where apidef.name like :"+QueryParams.KEY_API_NAME.getValue()+" and apidef.apiStatus=:"+QueryParams.KEY_API_STATUS.getValue();
        
            Map<String, Object> queryParams = new HashMap<String, Object>();System.out.println("------------===// API_NAME");
            queryParams.put(QueryParams.KEY_API_NAME.getValue(), apiName);
            queryParams.put(QueryParams.KEY_API_STATUS.getValue(), "ACTIVE");
        
            return getResults(query, queryParams);
            
        } else if (!systemName.equals(EMPTY_STRING) && packageName.equals(EMPTY_STRING) && !apiName.equals(EMPTY_STRING)) {  // SYSTEM_NAME && API_NAME
            
            final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo " +
                "where apidef.name like :"+QueryParams.KEY_API_NAME.getValue()+" and sysinfo.systemName=:"+QueryParams.KEY_SYSTEM_NAME.getValue()+" and apidef.apiStatus=:"+QueryParams.KEY_API_STATUS.getValue();
        
            Map<String, Object> queryParams = new HashMap<String, Object>();System.out.println("------------===// SYSTEM_NAME && API_NAME");
            queryParams.put(QueryParams.KEY_SYSTEM_NAME.getValue(), systemName);
            queryParams.put(QueryParams.KEY_API_NAME.getValue(), apiName);
            queryParams.put(QueryParams.KEY_API_STATUS.getValue(), "ACTIVE");
        
            return getResults(query, queryParams);
            
        }
         
        return null;
	}
	
	@SuppressWarnings("unchecked")
    private List<ApiDefinition> getResults(final String query, final Map<String, Object> queryParams) throws Exception {
	    
	       HibernateTemplate template = getHibernateTemplate();
	        
	        return (List<ApiDefinition>) template.execute(new HibernateCallback() {
	            public List doInHibernate(Session session)
	                    throws HibernateException {

	                Query q = session.createQuery(query);System.out.println("----------"+query);
	                q.setParameter(QueryParams.KEY_API_STATUS.getValue(), queryParams.get(QueryParams.KEY_API_STATUS.getValue()));
	                
                    if(queryParams.containsKey(QueryParams.KEY_API_NAME.getValue())) {
                        
                        String apiString = (String) queryParams.get(QueryParams.KEY_API_NAME.getValue());
                        System.out.println("''''''''''''''''''''"+apiString);
                        if(apiString.startsWith("*") && apiString.endsWith("*")) {
                            apiString = apiString.substring(1, apiString.length()-1);
                            q.setParameter(QueryParams.KEY_API_NAME.getValue(), "%"+apiString+"%");
                        } else if (apiString.startsWith("*")) {
                            apiString = apiString.substring(1);
                            q.setParameter(QueryParams.KEY_API_NAME.getValue(), "%"+apiString);                   
                        } else if (apiString.endsWith("*")) {
                            apiString = apiString.substring(0, apiString.length()-1);
                            q.setParameter(QueryParams.KEY_API_NAME.getValue(), apiString+"%");  
                        } else {
                            q.setParameter(QueryParams.KEY_API_NAME.getValue(), apiString);
                        }
                    }

                    if(queryParams.containsKey(QueryParams.KEY_SYSTEM_NAME.getValue())) {
                        q.setParameter(QueryParams.KEY_SYSTEM_NAME.getValue(), queryParams.get(QueryParams.KEY_SYSTEM_NAME.getValue()));
                       
                    }
                    
                    if(queryParams.containsKey(QueryParams.KEY_PACKAGE_NAME.getValue())) {
                        q.setParameter(QueryParams.KEY_PACKAGE_NAME.getValue(), queryParams.get(QueryParams.KEY_PACKAGE_NAME.getValue()));
                       
                    }
                    
	                return q.list();                
	            }
	        });
	}
	
	@SuppressWarnings("unchecked")
	public List<ApiDefinition> searchAPI(final ApiDefinition apiDefinition, final SystemInfo systemInfo) throws Exception {

		final String query = "select apidef from ApiDefinition apidef inner join apidef.systemInfo as sysinfo where apidef.name like :lik and sysinfo.systemName=:sys and apidef.packageHierachy=:pak";
		
		HibernateTemplate template = getHibernateTemplate();
		
        return (List<ApiDefinition>) template.execute(new HibernateCallback() {
            public List doInHibernate(Session session)
                    throws HibernateException {

                Query q = session.createQuery(query);
                
                String apiString = apiDefinition.getName();

                if(apiString.startsWith("*") && apiString.endsWith("*")) {
                	apiString = apiString.substring(1, apiString.length()-1);
                    q.setParameter("lik", "%"+apiString+"%");
                } else if (apiString.startsWith("*")) {
                	apiString = apiString.substring(1);
                    q.setParameter("lik", "%"+apiString);                	
                } else if (apiString.endsWith("*")) {
                	apiString = apiString.substring(0, apiString.length()-1);
                	q.setParameter("lik", apiString+"%");  
                } else {
                	q.setParameter("lik", apiString);
                }

                q.setParameter("sys", systemInfo.getSystemName());
                q.setParameter("pak", apiDefinition.getPackageHierachy());
                
                return q.list();                
            }
        });
	}
	
	enum QueryParams {
	    KEY_SYSTEM_NAME("sys"), KEY_PACKAGE_NAME("pak"), KEY_API_NAME("lik"), KEY_API_STATUS("ACTIVE");
	    
	    private String value;
	    
	    private QueryParams(String value) {
	        this.value = value;
	    }
	    
	    public String getValue() {
	        return value;
	    }
	};

}
